﻿using System;
using System.Collections.Generic;
using System.Net.Sockets;
using Server;

namespace Client
{
	internal interface IHandler
	{
		void Accept(ISerializable obj);
	}

	internal class AHandler : IHandler
	{
		#region Implementation of IHandler

		public void Accept(ISerializable obj)
		{
			var a = obj as A;
			if (a != null)
			{
				Console.WriteLine("AHandler accepted {0}", a.Value);
			}
		}

		#endregion
	}

	internal class BHandler : IHandler
	{
		#region Implementation of IHandler

		public void Accept(ISerializable obj)
		{
			var b = obj as B;
			if (b != null)
			{
				Console.WriteLine("BHandler accepted {0}", b.Value);
			}
		}

		#endregion
	}

	internal class Program
	{
		private static readonly List<ISerializable> _prototypes = new List<ISerializable> {new A(), new B(), new C()};
		private static readonly List<IHandler> _handlers = new List<IHandler> {new AHandler(), new BHandler()};

		private static void Main(string[] args)
		{
			if (args.Length < 1)
			{
				Console.WriteLine("Usage: client <host>");
				return;
			}

			var client = new TcpClient(args[0], 15000);
			NetworkStream stream = client.GetStream();
			for (int i = 0; i < 5*3; ++i)
			{
				var sizeData = new byte[sizeof (int)];
				stream.Read(sizeData, 0, sizeof (int));
				int size = BitConverter.ToInt32(sizeData, 0);
				var data = new byte[size];
				stream.Read(data, 0, size);
				foreach (ISerializable proto in _prototypes)
				{
					ISerializable receivedObj = proto.Deserialize(data);
					if (receivedObj != null)
					{
						receivedObj.Execute();
						_handlers.ForEach(handler => handler.Accept(receivedObj));
						break;
					}
				}
			}
		}
	}
}